/**
 * @author Matan Mizrahi,Chen weissman
 * Introduction to computer science, assingment5
 * Date:2.1.2011
 *
 * The Multiplication class, in which implement the Expression Interface
 * represents the Multiplication Expression (i.e., a*b, where a and b are expressions as well)
 * A multiplication expression can be evaluated, derived and return its last operation symbol.
 *
 */
public class Multiplication implements Expression {

    private Expression ex1;
    private Expression ex2;

    /**
     * Constructor that creates a multiplication expression composed of the two expressions
     *
     * @param ex1  the ex1 expression
     * @param ex2 the ex2 expression
     * @throws RunTimeException for null input expressions
     */
    public Multiplication(Expression ex1, Expression ex2) {
        if ((ex1 == null) || (ex2 == null)) {
            throw new RuntimeException("Multiplication constructor got a null argument.");
        }
        this.ex1 = ex1;
        this.ex2 = ex2;
    }

    /**
     * Returns the last operation symbol of multiplication expression
     *
     * @return String "*" that represents the last operation
     */
    public String getLastOperationSymbol() {
        return "*";
    }

    /**
     * Evaluate the multiplication expression
     *
     * @return double that represents the evaluation of the multiplication expression
     */
    public double evaluate(Assignment assign) {
        return ex1.evaluate(assign) * ex2.evaluate(assign);
    }

    /**
     * Derives the multiplication expression by a variable.
     *
     * @param var the variable to derive by
     * @return the derived expression by @param name
     */
    public Expression derivative(char name) {
        
        Expression additionex1 = new Multiplication(ex1,
                ex2.derivative(name));
        Expression additionex2 = new Multiplication(ex1.derivative(name),
                ex2);
        return new Addition(additionex1,
                additionex2);
    }

    /**
     * Compares this multiplication expression to the specified object.
     * The result is true if and only if the argument is not null, the argument is instance of Multiplication expression and the sub-expressions are equals.
     *
     * @param other The object to compare this expression against
     * @return true if the given object represents an expression equivalent to this expression, false otherwise
     */
    public boolean equals(Object other) {
        return ((other instanceof Multiplication) &&
                (ex1.equals(((Multiplication) other).ex1)) &&
                (ex2.equals(((Multiplication) other).ex2)));
    }


    /**
     * Returns a string representing the Multiplication Expression.
     *
     * @return String that represents the Multiplication Expression
     */
    public String toString() {
        return "(" + ex1.toString() + getLastOperationSymbol() + ex2.toString() + ")";
    }

	/**
	 * Replicating the invoking object.
	 * 
	 * @return a replicate of this object. The returned object has
	 * to be a new object (with a different address than this
	 * object), but equivalent to the this object under the 
	 * application of the {@code equals(Object other)} method.
	 */
public Expression replicate(){
	return new Multiplication( ex1, ex2);
}
}



